﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

/*
 * Służy do wizualizacji sfer otaczających.
 * Tworzy listę wierzchołków, które służą do narysowania sfery.
 * Wierzchołki są obliczone dla sfery o średnicy = 1.
 * Sfera zostaje przeskalowana dopiero przy renderowaniu.
 */
namespace Projekt.Models.Primitives
{
    public static class BoundingSphereRender
    {
        static BasicEffect basicEffect;
        // Lista tablic, które przechowują wierzchołki dla każdego okręgu
        static List<VertexPositionColor[]> vertices;

        /// <summary>
        /// Inicjalizacja wierzchołków.
        /// Jeśli nie wywołano wcześniej, zostanie uruchomiona w momencie pierwszego użycia
        /// </summary>
        /// <param name="graphicsDevice"></param>
        public static void Initialize(GraphicsDevice graphicsDevice)
        {
            basicEffect = new BasicEffect(graphicsDevice);
            basicEffect.VertexColorEnabled = true;

            vertices = new List<VertexPositionColor[]>(3);

            // Wypełniamy listę tablic wierzchołków wierzchołkami o podanych pozycjach
            for (int i = 0; i < 3; i++)
            {
                vertices.Add(new VertexPositionColor[100]);
                for (int j = 0; j < 100; j++)
                {
                    float angle = (float)(j / 100.0 * Math.PI * 2);
                    switch (i)
                    {
                        case 0:
                            vertices.Last()[j].Position = new Vector3((float)Math.Cos(angle), (float)Math.Sin(angle), 0);
                            break;
                        case 1:
                            vertices.Last()[j].Position = new Vector3((float)Math.Cos(angle), 0, (float)Math.Sin(angle));
                            break;
                        case 2:
                            vertices.Last()[j].Position = new Vector3(0, (float)Math.Cos(angle), (float)Math.Sin(angle));
                            break;
                    }
                    vertices.Last()[j].Color = Color.White;
                }
                vertices.Last()[99] = vertices.Last()[0];
            }
        }

        /// <summary>
        /// Wyświetla sferę o podanym kolorze
        /// </summary>
        /// <param name="sphere">Sfera otaczająca do wyświetlenia</param>
        /// <param name="graphicsDevice"></param>
        /// <param name="View">Macierz widoku</param>
        /// <param name="Projection">Macierz projekcji</param>
        /// <param name="color">Kolor sfery</param>
        public static void Render(BoundingSphere sphere, GraphicsDevice graphicsDevice, Matrix View, Matrix Projection, Color color)
        {
            if (basicEffect == null) Initialize(graphicsDevice);

            basicEffect.Projection = Projection;
            basicEffect.View = View;
            // Obliczanie macierzy transformacji dla sfery.
            // Tutaj sfera jest przesuwana i przeskalowana.
            basicEffect.World = Matrix.CreateScale(sphere.Radius) * Matrix.CreateTranslation(sphere.Center);
            // Ustalenie koloru dla krawędzi sfery.
            basicEffect.DiffuseColor = color.ToVector3();
            basicEffect.CurrentTechnique.Passes[0].Apply();
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices[0], 0, 99);
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices[1], 0, 99);
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices[2], 0, 99);
        }

    }
}
